#ifndef KERNEL_HAL_x86_IDT_H
#define KERNEL_HAL_x86_IDT_H

#include "Hal/IHardware.h"
#include "Hal/ITaskContext.h"

#define IDT_TRACE(x ...) HAL_TRACE_DETAILED("IDT: " x)

namespace x86
{
	struct Registers;

    enum
    {
        IRQ_0 = 0x20,
        IRQ_1,
        IRQ_2,
        IRQ_3,
        IRQ_4,
        IRQ_5,
        IRQ_6,
        IRQ_7,
        IRQ_8,
        IRQ_9,
        IRQ_10,
        IRQ_11,
        IRQ_12,
        IRQ_13,
        IRQ_14,
        IRQ_15,
    };

	enum
	{
		INT_DIVIDE_ERROR = 0x00,
		INT_DEBUG,
		INT_NON_MASKABLE_INTERRUPT,
		INT_BREAK_POINT,
		INT_OVERFLOW,
		INT_BOUNDARY_RANGE_EXCEEDED,
		INT_UNDEFINED_OP_CODE,
		INT_DEVICE_NOT_AVAILABLE,
		INT_DOUBLE_FAULT,
		__INT_RESERVED_0,
		INT_INVALID_TSS,
		INT_NOT_PRESENT,
		INT_STACK_SEGMENT,
		INT_GENERAL_PROTECTION,
		INT_PAGE_FAULT,
		__INT_RESERVED_1,
		INT_MATH_FAULT,
		INT_ALIGNMENT_CHECKING,
		INT_MACHINE_CHECK,
		INT_EXTENDED_MATH_FAULT,

		INT_IRQ_0 = 0x20,
		INT_IRQ_1,
		INT_IRQ_2,
		INT_IRQ_3,
		INT_IRQ_4,
		INT_IRQ_5,
		INT_IRQ_6,
		INT_IRQ_7,
		INT_IRQ_8,
		INT_IRQ_9,
		INT_IRQ_10,
		INT_IRQ_11,
		INT_IRQ_12,
		INT_IRQ_13,
		INT_IRQ_14,
		INT_IRQ_15,
	};

	class IDT
	{
	public:
		static Result Initialize( void );
		static Result RegisterHandler( int interrupt, InterruptHandler handler );
		static void DefaultHandler( ITaskContext * context );

	private:
		static void InitializeEntry( int index, uint32 offset, uint8 flags );
	};
}

#endif // KERNEL_HAL_x86_IDT_H
